<template>
  <div class="table-layout-container">
    <el-button icon="el-icon-document" type="text" @click="$router.go(-1)">
      返回
    </el-button>
    <!-- 组件工具栏 -->
    <div class="component-palette">
      <div class="palette-header">表单组件</div>
        <draggable v-model="arr1" group="site" animation="300" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
          <transition-group>
              <div class="item" v-for="item in arr1" :key="item.id">{{item.name}}</div>
          </transition-group>
      </draggable>
    </div>
    <!-- 动态表格区域 -->
    <div class="editable-table" @click.self="clearSelection">
      <table>
        <tr v-for="(row, rowIndex) in tableData" :key="rowIndex">
          <td
            v-for="(cell, colIndex) in row"
            :key="cell.id"
            :rowspan="cell.rowspan"
            :colspan="cell.colspan"
            :class="[
              'cell-item',
              {
                'active-cell':
                  activeCell.row === rowIndex && activeCell.col === colIndex,
                'merged-cell': cell.merged,
                'hidden-cell': !cell.visible,
              },
            ]"
            draggable="true"
            @dragstart="handleCellDragStart($event,rowIndex, colIndex)"
            @contextmenu.prevent="showContextMenu($event, rowIndex, colIndex)"
            @click.stop="handleCellClick(rowIndex, colIndex, $event)"
          >
            <div class="cell-content">
              <div
                class="drop-zone"
                @dragover.prevent
                @drop="handleDrop($event, cell, rowIndex, colIndex)"
              >
              <draggable v-model="children" group="site" animation="100" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
                <transition-group :style="emptyStyle">
                  <div class="item" v-for="item in children" :key="item.id">
                      <div v-if="!item.name" class="empty-tip">
                      请从左侧拖入组件
                    </div>
                    <div>
                      {{item.name}}
                    </div>
                  </div>
                </transition-group>
              </draggable>
              <div v-show="!children.length" class="empty-tip">
                请从左侧拖入组件
              </div>
              </div>
              <div class="cell-actions">
                <el-button-group class="action-buttons">
                  <el-button v-for="action in cellActions" :key="action.type" size="mini" circle
                    @click.stop="handleCellAction(action.type, rowIndex, colIndex)">
                    <i :class="action.icon"></i>
                    <!--<i v-if="action.type !== 'other-actions'" :class="action.icon"></i>
                     <el-dropdown v-else>
                       <i :class="action.icon"></i>
                      <el-dropdown-menu slot="dropdown">
                        <div>
                          <template v-for="(item, index) in contextMenuItems">
                            <div
                              v-if="item.type === 'separator'"
                              :key="`sep-${index}`"
                              class="menu-separator"
                            ></div>
                            <div
                              v-else
                              :key="item.command"
                              class="menu-item"
                              @click="handleMenuCommand(item.command)"
                            >
                              <i :class="item.icon"></i>
                              {{ item.label }}
                            </div>
                          </template>
                        </div>
                      </el-dropdown-menu>
                    </el-dropdown> -->
                  </el-button>
                </el-button-group>
              </div>
            </div>
          </td>
        </tr>
      </table>
    </div>
    <!-- 右键菜单 -->
    <div
      v-show="contextMenu.visible"
      class="context-menu"
      :style="menuPosition"
    >
      <template v-for="(item, index) in contextMenuItems">
        <div
          v-if="item.type === 'separator'"
          :key="`sep-${index}`"
          class="menu-separator"
        ></div>
        <div
          v-else
          :key="item.command"
          class="menu-item"
          @click="handleMenuCommand(item.command)"
        >
          <i :class="item.icon"></i>
          {{ item.label }}
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { Input, Select, DatePicker, Switch, Button } from "element-ui";
import draggable from "vuedraggable";
import { v4 as uuidv4 } from 'uuid';
const CELL_DEFAULT = {
  rowspan: 1,
  colspan: 1,
  merged: false,
  visible: true,
  component: null,
};

export default {
  components: {
    ElInput: Input,
    ElSelect: Select,
    ElDatePicker: DatePicker,
    ElSwitch: Switch,
    ElButton: Button,
    draggable,
  },
  data() {
    return {
      components: [
        { type: "ElInput", label: "输入框", icon: "el-icon-edit" },
        { type: "ElSelect", label: "下拉框", icon: "el-icon-arrow-down" },
        { type: "ElDatePicker", label: "日期", icon: "el-icon-date" },
        { type: "ElSwitch", label: "开关", icon: "el-icon-switch" },
      ],
      tableData: this.initTable(2, 3), // 默认两行3列
      activeCell: { row: -1, col: -1 },
      contextMenu: {
        visible: false,
        position: { x: 0, y: 0 },
        row: -1,
        col: -1,
      },
      children: [],
      cellActions: [
        { type: "add-left", icon: "el-icon-s-fold" },
        { type: "add-right", icon: "el-icon-s-unfold" },
        { type: "add-top", icon: "el-icon-top" },
        { type: "add-bottom", icon: "el-icon-bottom" },
        // { type: "other-actions", icon: "el-icon-menu" },
      ],
      drag: false,
      arr1: [
          { id: 1, name: 'www.itxst.com' },
          { id: 2, name: 'www.jd.com' },
          { id: 3, name: 'www.baidu.com' },
          { id: 4, name: 'www.taobao.com' },
          { id: 5, name: 'www.msn.com' },
          { id: 6, name: 'www.ebay.com' },
          { id: 7, name: 'www.yahoo.com' }
      ],
      // 空数组之在的样式，设置了这个样式才能拖入
      emptyStyle:'min-height:120px;display: block;',
    };
  },
  computed: {
    menuPosition() {
      return {
        left: `${this.contextMenu.position.x}px`,
        top: `${this.contextMenu.position.y}px`,
      };
    },
    contextMenuItems() {
      return [
        {
          command: "add-col-left",
          label: "左侧插入列",
          icon: "el-icon-circle-plus-outline",
        },
        {
          command: "add-col-right",
          label: "右侧插入列",
          icon: "el-icon-circle-plus-outline",
        },
        {
          command: "add-row-top",
          label: "上方插入行",
          icon: "el-icon-circle-plus-outline",
        },
        {
          command: "add-row-bottom",
          label: "下方插入行",
          icon: "el-icon-circle-plus-outline",
        },
        { type: "separator" },
        {
          command: "merge-right",
          label: "向右合并",
          icon: "el-icon-d-arrow-right",
        },
        {
          command: "merge-down",
          label: "向下合并",
          icon: "el-icon-arrow-down",
        },
        { type: "separator" },
        { command: "split-cell", label: "拆分单元格", icon: "el-icon-rank" },
        { type: "separator" },
        { command: "delete-row", label: "删除当前行", icon: "el-icon-remove" },
        { command: "delete-col", label: "删除当前列", icon: "el-icon-remove" },
      ];
    },
  },
  methods: {
    onStart() {
        this.drag = true;
    },
    onEnd() {
        this.drag = false;
    },
    initTable(rows, cols) {
      return Array.from({ length: rows }, (_, i) =>
        Array.from({ length: cols }, (_, j) => ({
          ...CELL_DEFAULT,
          id: uuidv4() // 每个单元格独立生成UUID
        }))
      );
    },
    // 新增克隆方法
    // handleCloneComponent(comp) {
    //   return { ...comp };
    // },
    getComponentProps(type) {
      const propsMap = {
        ElInput: {
          placeholder: "请输入",
          clearable: true,
          size: "small",
        },
        ElSelect: {
          placeholder: "请选择",
          options: [
            { value: "option1", label: "选项一" },
            { value: "option2", label: "选项二" },
          ],
          filterable: true,
        },
        ElDatePicker: {
          type: "date",
          placeholder: "选择日期",
          valueFormat: "yyyy-MM-dd",
        },
        ElSwitch: {
          activeText: "启用",
          inactiveText: "停用",
          activeColor: "#13ce66",
        },
      };
      return { ...propsMap[type], style: "width: 100%" };
    },
    // 拖拽开始处理--从表格拖出
    handleCellDragStart(event,row, col) {
      console.log('cellId--->', event,row, col);
      event.dataTransfer.setData("cellId", `${row}-${col}`);
      if (this.tableData[row][col].component) {
        event.dataTransfer.setData("text/source-row", row);
        event.dataTransfer.setData("text/source-col", col);
        event.dataTransfer.effectAllowed = "move";
      }
    },
    handleCellClick(row, col, event) {
      this.activeCell = { row, col };
      if (event.shiftKey) {
        this.selectedCells.push({ row, col });
      } else {
        this.selectedCells = [{ row, col }];
      }
    },

    // 合并逻辑优化
    mergeCells(direction) {
      const { row, col } = this.contextMenu;
      const cell = this.tableData[row][col];

      if (direction === "right") {
        let colspan = 1;
        while (
          col + colspan < this.tableData[row].length &&
          !this.tableData[row][col + colspan].merged &&
          !this.tableData[row][col + colspan].component
        ) {
          // 隐藏被合并单元格时不修改其ID
          this.tableData[row][col + colspan].visible = false;
          colspan++;
        }
        if (colspan > 1) {
          cell.colspan = colspan;
          cell.merged = true;
        }
      } else if (direction === "down") {
        let rowspan = 1;
        while (
          row + rowspan < this.tableData.length &&
          !this.tableData[row + rowspan][col].merged &&
          !this.tableData[row + rowspan][col].component
        ) {
          // 隐藏被合并单元格时不修改其ID
          this.tableData[row + rowspan][col].visible = false;
          rowspan++;
        }
        if (rowspan > 1) {
          cell.rowspan = rowspan;
          cell.merged = true;
        }
      }
      this.$forceUpdate();
    },

    // 拆分逻辑优化
    splitCell() {
      const { row, col } = this.contextMenu;
      const cell = this.tableData[row][col];

      // 恢复被隐藏的单元格
      for (let i = row; i < row + cell.rowspan; i++) {
        for (let j = col; j < col + cell.colspan; j++) {
          if (i !== row || j !== col) {
            this.tableData[i][j].visible = true;
          }
        }
      }

      // 重置主单元格
      cell.rowspan = 1;
      cell.colspan = 1;
      cell.merged = false;
      this.$forceUpdate();
    },

    // 行列操作
    handleCellAction(action, row, col) {
      const actions = {
        // "add-left": () => this.addCol(col),
        // "add-right": () => this.addCol(col + 1),
        "add-top": () => this.addRow(row),
        "add-bottom": () => this.addRow(row + 1),
      };
      actions[action]?.();
    },

    addRow(row) {
      // debugger
      const newRow = this.tableData[0].map(() => ({
        ...CELL_DEFAULT,
        id: uuidv4() // 新行每个单元格独立生成UUID
      }));
      this.tableData.splice(row, 0, newRow);
      console.log('this.tableData~~~~~~~~', this.tableData);
    },

    addCol(index) {
      this.tableData.forEach(row => {
        row.splice(index, 0, {
          ...CELL_DEFAULT,
          id: uuidv4() // 每行新列单元格独立生成UUID
        });
      });
    },

    deleteRow() {
      this.tableData.splice(this.contextMenu.row, 1);
    },

    deleteCol() {
      this.tableData.forEach(row => row.splice(this.contextMenu.col, 1));
    },

    // 事件处理
    handleDrop(e, cell, row, col) {
      console.log('hjgjghj', e, cell, row, col);
      const sourceId = e.dataTransfer.getData("cellId");
      if (sourceId && sourceId !== cell.id) {
        const [srcRow, srcCol] = this.findCellIndexById(sourceId);
        const tempComponent = this.tableData[srcRow][srcCol].component;
        this.$set(this.tableData[srcRow][srcCol], "component", null);
        this.$set(this.tableData[row][col], "component", tempComponent);
      }
      // 1. 获取拖拽数据源标识
      const componentType = e.dataTransfer.getData("text/component-type");
      const sourceRow = parseInt(e.dataTransfer.getData("sourceRow"));
      const sourceCol = parseInt(e.dataTransfer.getData("sourceCol"));
      const cellId = e.dataTransfer.getData("cellId"); // 单元格唯一ID

      // 2. 校验目标单元格合法性
      if (this.tableData[row][col].merged) {
        this.$message.warning("合并单元格不能放置组件");
        return;
      }
      if (this.tableData[row][col].component && !cellId) {
        this.$message.warning("该单元格已有组件");
        return;
      }

      // 3. 单元格间拖拽交换逻辑
      if (cellId === `${row}-${col}`) return; // 禁止原地拖拽
      if (cellId) {
        const [srcRow, srcCol] = cellId.split('-').map(Number);
        const tempComponent = this.tableData[srcRow][srcCol].component;
        this.$set(this.tableData[srcRow][srcCol], "component", null);
        this.$set(this.tableData[row][col], "component", tempComponent);
        return;
      }

      // 4. 新增组件逻辑
      if (componentType) {
        this.$set(this.tableData[row][col], "component", {
          type: componentType,
          props: this.getComponentProps(componentType),
          value: null,
          cellId: `${row}-${col}` // 绑定唯一单元格ID
        });
      }
    },
    // 根据ID查找单元格坐标
    findCellIndexById(id) {
      for (let i = 0; i < this.tableData.length; i++) {
        for (let j = 0; j < this.tableData[i].length; j++) {
          if (this.tableData[i][j].id === id) return [i, j];
        }
      }
      return [-1, -1];
    },
    // 添加单元格拖拽处理
    handleCellDrag(startRow, startCol, endRow, endCol) {
      const sourceCell = this.tableData[startRow][startCol];
      const targetCell = this.tableData[endRow][endCol];

      if (!targetCell.merged && !targetCell.component) {
        // 交换单元格内容
        const tempComponent = sourceCell.component;
        this.$set(sourceCell, "component", null);
        this.$set(targetCell, "component", tempComponent);
      }
    },
    getComponentProps(type) {
      const propsMap = {
        ElInput: { placeholder: "请输入内容", clearable: true },
        ElSelect: { placeholder: "请选择", options: ["选项1", "选项2"] },
        ElDatePicker: { type: "date", placeholder: "选择日期" },
        ElSwitch: { activeText: "是", inactiveText: "否" },
      };
      return { 
          ...propsMap[type],
          style: "width: calc(100% - 8px); margin: 4px" // 防止溢出
        };
      },

    // 上下文菜单
    showContextMenu(e, row, col) {
      this.contextMenu = {
        visible: true,
        position: { x: e.pageX, y: e.pageY },
        row,
        col,
      };
      this.activeCell = { row, col };
    },

    handleMenuCommand(command) {
      const actions = {
        "merge-right": () => this.mergeCells("right"),
        "merge-down": () => this.mergeCells("down"),
        "split-cell": this.splitCell,
        "delete-row": this.deleteRow,
        "delete-col": this.deleteCol,
        "add-col-left": () => this.addCol(this.contextMenu.col),
        "add-col-right": () => this.addCol(this.contextMenu.col + 1),
        "add-row-top": () => this.addRow(this.contextMenu.row),
        "add-row-bottom": () => this.addRow(this.contextMenu.row + 1),
      };
      actions[command]?.();
      this.contextMenu.visible = false;
    },

    clearSelection() {
      this.activeCell = { row: -1, col: -1 };
    },
  },
};
</script>

<style scoped>
.table-layout-container {
  display: flex;
  height: 100vh;
  background: #fff;
}

.component-palette {
  width: 240px;
  border-right: 1px solid #ebeef5;
  padding: 16px;
}

.component-item {
  padding: 12px;
  margin: 8px 0;
  border: 1px dashed #ddd;
  border-radius: 4px;
  cursor: move;
  transition: all 0.3s;
}

.component-item:hover {
  border-color: #409eff;
  background: #f5f7fa;
}

.editable-table {
  flex: 1;
  padding: 24px;
  overflow: auto;
}

table {
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
}

.cell-item {
  position: relative;
  min-width: 160px;
  height: 100px;
  border: 1px solid #dcdfe6;
  padding: 8px;
  transition: all 0.3s;
}

.active-cell {
  border-color: #409eff !important;
  box-shadow: inset 0 0 0 2px #409eff;
}

.merged-cell {
  background: #f0f9eb;
}

.hidden-cell {
  display: none;
}

.drop-zone {
  transition: all 0.3s ease;
  &.drag-over {
    background-color: rgba(64, 158, 255, 0.1);
    box-shadow: inset 0 0 12px rgba(64, 158, 255, 0.1);
  }
  &.disabled-drop {
    background-color: rgba(255, 73, 73, 0.1);
    cursor: not-allowed;
  }
}
.cell-item.drag-over {
  box-shadow: inset 0 0 12px rgba(64,158,255,0.2);
  background: #f8fafc;
}
.cell-actions {
  position: absolute;
  top: 4px;
  right: 4px;
  opacity: 0;
  transition: opacity 0.3s;
}

.cell-item:hover .cell-actions {
  opacity: 1;
}

.context-menu {
  position: fixed;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  z-index: 2000;
}

.menu-item {
  padding: 8px 16px;
  cursor: pointer;
  transition: all 0.3s;
}

.menu-item:hover {
  background: #f5f7fa;
}
</style>
 <style>
        /*定义要拖拽元素的样式*/
        .ghostClass {
            background-color: blue !important;
        }

        .chosenClass {
            background-color: red !important;
            opacity: 1 !important;
        }

        .dragClass {
            background-color: blueviolet !important;
            opacity: 1 !important;
            box-shadow: none !important;
            outline: none !important;
            background-image: none !important;
        }

        .itxst {
            margin: 10px;
        }

        .title {
            padding: 6px 12px;
        }

        .col {
            width: 40%;
            flex: 1;
            padding: 10px;
            border: solid 1px #eee;
            border-radius: 5px;
            float: left;
        }

         .col + .col {
                margin-left: 10px;
            }
        .item {
            padding: 6px 12px;
            margin: 0px 10px 0px 10px;
            border: solid 1px #eee;
            background-color: #f1f1f1;
        }

            .item:hover {
                background-color: #fdfdfd;
                cursor: move;
            }

            .item + .item {
                border-top: none;
                margin-top: 6px;
            }
    </style>